package home

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"minititok/Entities"
	"minititok/Services"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

func getVideo(c *gin.Context) {
	type RequestBody struct {
		Likes int `json:"likes"`
	}
	var body RequestBody
	if err := c.ShouldBindJSON(&body); err != nil {
		_ = c.Error(fmt.Errorf("请求不正确:" + err.Error()))
		c.JSON(http.StatusBadRequest, gin.H{"customMessage": "请求不正确"})
		return
	}

	var videos []Entities.Video
	var err error
	user, _ := c.Get("user")
	currUser, erruser := user.(*Entities.User)
	if !erruser {
		_ = c.Error(fmt.Errorf("token验证失败:%w", err))
		c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "token验证失败"})
		return
	}
	if body.Likes == -1 {
		videos, err = Services.FindFiveOrderByLikes(currUser.Username)
	} else {
		videos, err = Services.FindFiveNotWatchedWithPrefix(currUser.Username)
	}
	if err != nil {
		_ = c.Error(fmt.Errorf("视频推荐查找错误:" + err.Error()))
		c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "服务器内部错误"})
		return
	}

	data := gin.H{
		"items":    []gin.H{},
		"has_more": false,
	}
	if len(videos) > 0 {
		if len(videos) > 4 {
			data["has_more"] = true
		}
		var items []gin.H
		for _, item := range videos {
			author, errVideoUser := Services.FindUserByUsername(item.Author)
			if errVideoUser != nil {
				_ = c.Error(fmt.Errorf("视频信息错误, 视频无主: %v, Av号: AV%d", errVideoUser, item.Av))
				c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "视频信息错误"})
				return
			}
			intAv := strconv.Itoa(int(item.Av))
			likes, likesErr := Services.EnsureLikes(currUser.Username, intAv)
			if likesErr != nil {
				_ = c.Error(fmt.Errorf("视频信息错误: %v", likesErr))
				c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "视频信息错误"})
				return
			}
			favorite, favErr := Services.Ensurefavorites(currUser.Username, intAv)
			if favErr != nil {
				_ = c.Error(fmt.Errorf("视频信息错误: %v", favErr))
				c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "视频信息错误"})
				return
			}
			items = append(items, gin.H{
				"av":       "Av" + strconv.Itoa(int(item.Av)),
				"title":    item.Title,
				"videoUrl": item.VideoURL,
				"author": gin.H{
					"nickname": author.Nickname,
					"avatar":   "http://localhost:8000/getAvatar/default.jpg",
					"uid":      author.UID,
				},
				"stats": gin.H{
					"likes":       item.Likes,
					"comments":    item.Comments,
					"collects":    item.Collects,
					"views":       item.Views,
					"description": item.Description,
				},
				"createTime":    item.CreateDate,
				"has_likes":     likes.Liked,
				"has_favorites": favorite.Favorited,
			})
		}
		data["items"] = items
	}
	c.JSON(http.StatusOK, data)
}

func reVideo(c *gin.Context) {
	filename := c.Param("filename")
	filepath := filepath.Join("./staticSrc/staticVideo/", filename)
	if c.Request.Method != http.MethodGet {
		_ = c.Error(fmt.Errorf("请求方式错误:" + c.Request.Method))
		c.String(http.StatusNotFound, "<h1>Page not found</h1>")
		return
	}
	if _, err := os.Stat(filepath); os.IsNotExist(err) {
		_ = c.Error(fmt.Errorf("视频不存在:" + filepath))
		c.JSON(http.StatusNotFound, gin.H{"customMessage": "视频不见了"})
		return
	}
	c.Header("Accept-Ranges", "bytes")
	c.File(filepath)
}

func getCover(c *gin.Context) {
	rawPath := c.Param("filename")
	filename, err := url.PathUnescape(strings.TrimPrefix(rawPath, "/"))
	if err != nil {
		_ = c.Error(fmt.Errorf("文件名解析失败:%s,来自文件:%s", err.Error(), filename))
		c.JSON(http.StatusBadRequest, gin.H{"error": "文件名解析失败"})
		return
	}
	filePath := filepath.Join("./staticSrc/staticCover/", filename)
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		_ = c.Error(fmt.Errorf("文件不存在,来自路径:" + filePath))
		c.JSON(http.StatusNotFound, gin.H{"customMessage": "封面不存在"})
		return
	}
	c.File(filePath)
}

func WatchedVideo(c *gin.Context) {
	type Response struct {
		Av string `json:"av"`
	}
	var body Response
	errBody := c.ShouldBindJSON(&body)
	if errBody != nil {
		_ = c.Error(fmt.Errorf("请求参数错误:%s", errBody))
		c.JSON(http.StatusBadRequest, gin.H{"customMessage": "请求参数错误"})
	}
	av := body.Av
	av = av[2:]
	user, Uerr := c.Get("user")
	if !Uerr {
		_ = c.Error(fmt.Errorf("token验证失败"))
		c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "token验证失败"})
		return
	}
	currUser, _ := user.(*Entities.User)
	hadWatch := Entities.HadWatch{
		Username: currUser.Username,
		Av:       av,
	}
	err := Services.HandWatchVideo(&hadWatch)
	if err != nil {
		c.Error(fmt.Errorf("数据库错误储存失败:%s", err))
		c.JSON(http.StatusUnauthorized, gin.H{"customMessage": "服务器内部错误"})
		return
	}
	c.JSON(200, gin.H{"customMessage": "success"})
}
